﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using UPNP.IO;

namespace UPNP.Inspector
{
	public partial class RouterInspector : UserControl
	{
        public class ServiceEntry
        {
            [Browsable(true)]
            public DeviceService Service
            {
                get; 
                private set;
            }

            [Browsable(true), TypeConverter(typeof(CollectionConverter))]
            public IDictionary<string, object> StateVariables
            {
                get;
                private set;
            }

            public ServiceEntry(DeviceService s)
            {
                this.Service = s;
                this.StateVariables = new Dictionary<string, object>();

                foreach (var kvp in s.GetAllVariableValues())
                    this.StateVariables.Add(kvp);
            }
        }

		public RouterInspector()
		{
			InitializeComponent();

			ResetTreeView();
		}

        private void ResetTreeView()
        {
            this.treeView.Nodes.Clear();
            this.treeView.Nodes.Add("Searching...");
        }

        private void ScanForDevices()
        {
            this.UseWaitCursor = true;
            this.menuStrip.Enabled = false;

            this.backgroundDeviceFinder.RunWorkerAsync();
        }

		private void RouterInspector_Load(object sender, EventArgs e)
		{
            if (System.ComponentModel.LicenseManager.UsageMode != System.ComponentModel.LicenseUsageMode.Designtime)
                ScanForDevices();
		}

		private void LoadDevicesOfTreeNode(TreeNodeCollection root, IEnumerable<Device> devices)
		{
			this.UseWaitCursor = true;
            this.menuStrip.Enabled = false;
            this.treeView.SuspendLayout();

			try
			{
				root.Clear();

				// add devices
				foreach (var d in devices)
				{
					var tn = new TreeNode();

					tn.Text = "Device: " + d.FriendlyName;
					tn.ToolTipText = d.UniqueDeviceName;
					tn.Tag = d;

					// has children?
					if (d.HasChildren || (d.Services.Count > 0))
						tn.Nodes.Add("Loading...");

					root.Add(tn);
				}
			}
			finally
			{
				this.treeView.ResumeLayout();
				this.UseWaitCursor = false;
                this.menuStrip.Enabled = true;
			}

		}

		private void LoadServicesOfTreeNode(TreeNodeCollection root, IEnumerable<DeviceService> services)
		{
			this.UseWaitCursor = true;
			this.treeView.SuspendLayout();

			try
			{
				// add services
				foreach (var d in services)
				{
                    // add service
					var tn = new TreeNode();

					tn.Text = "Service: " + d.ServiceTypeIdentifier;
					tn.ToolTipText = d.Id;
                    tn.Tag = new ServiceEntry(d);

					root.Add(tn);
				}
			}
			finally
			{
				this.treeView.ResumeLayout();
				this.UseWaitCursor = false;
			}

		}

		private void treeView_AfterExpand(object sender, TreeViewEventArgs e)
		{
			var tn = e.Node;
			var device = tn.Tag as Device;

			if (device != null)
			{
				LoadDevicesOfTreeNode(tn.Nodes, device.Children);
				LoadServicesOfTreeNode(tn.Nodes, device.Services);
			}
		}

		private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
		{
			var tn = e.Node;

			this.propertyGrid.SelectedObject = tn.Tag;

		}

		private void backgroundDeviceFinder_DoWork(object sender, DoWorkEventArgs e)
		{
			var devices = DeviceFinder.Instance.FindInternetGateway();

			var devices2 = new List<Device>(devices.Count);

			foreach (var d in devices)
				devices2.Add(d);

			e.Result = devices2.ToArray();
		}

		private void backgroundDeviceFinder_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			var devices2 = (Device[])e.Result;

			LoadDevicesOfTreeNode(this.treeView.Nodes, devices2);
		}

        private void rescanBtn_Click(object sender, EventArgs e)
        {
            ResetTreeView();
            ScanForDevices();
        }
	}
}
